<?php

class quizplugin extends WikiPlugin
{

	function quizplugin()
	{
		$this->add_filter('quiz', 10, '/^.*$/se', array(&$this, 'quiz'));
	}
	
/*
<legend>Breathing and Cardiac Emergencies Review</legend>

*To give care for an ill or injured person, you must first:*

*[Breathing and Cardiac Emergencies Review Question 41 Answer Correct|Obtain the person's consent.]
*[Breathing and Cardiac Emergencies Review Question 41 Answer Not Correct|Begin to write your record of what happened.]
*[Breathing and Cardiac Emergencies Review Question 41 Answer Not Correct|Ask bystanders what happened.]
*[Breathing and Cardiac Emergencies Review Question 41 Answer Not Correct|Find out if you have a duty to act.]

Information obtained from American Red Cross Lifeguard Training 2001

*/

/*

[Breathing and Cardiac Emergencies Review]

Q:To give care for an ill or injured person, you must first:
A*:Obtain the person's consent.
A:Begin to write your record of what happened.
A:Ask bystanders what happened.
A:Find out if you have a duty to act.

*/

/*   '/Q:.*?(?=^\\[|Q:|\\z)/sm'   */

	function quiz($matches, &$wiki)
	{
		$quizstate = isset($_POST['quizstate']) ? unserialize(gzuncompress(base64_decode($_POST['quizstate']))) : array('step' => 0);
		$quiztext = $matches[0];
		$output = '<form class="quiz" method="post">';
		
		if(isset($_POST['action'])) {
			switch($_POST['action']) {
			case 'Return to Menu':
				$quizstate['step'] = 1;
				break;
			case 'View Results':
				$complete = true;
				$this->get_menu($quiztext, $quizstate, $complete);
				if($complete) $quizstate['step'] = 4;
				break;
			}
		}
		
		switch($quizstate['step']) {
		case 0:
			$output .= $this->get_welcome($quiztext);
			$output .= '<div class="quiz_controls"><input type="submit" name="action" value="Start the Quiz" /></div>';
			$quizstate['step'] = 1;
			break;
		case 1:
			if(!isset($quizstate['start'])) $quizstate['start'] = time();
			$output .= '<p>Please choose a section:</p>';
			$complete = true;
			$output .= $this->get_menu($quiztext, $quizstate, $complete);
			if($complete) {
				$output .= '<div class="quiz_controls"><input type="submit" name="action" value="View Results" /></div>';
			}
			else {
				$output .= '<div class="quiz_controls"><input type="submit" name="action" value="View Questions" /></div>';
			}
			$quizstate['step'] = 2;
			break;
		case 2:
			if(isset($_POST['quizsection'])) $quizstate['section'] = $_POST['quizsection'];
			$output .= '<div class="quiz_topic">' . $quizstate['section'] . '</div>';

			$q = $this->get_questions($quiztext);
			$q = $q[$quizstate['section']];

			if(isset($_POST['quiz_answer'])) {
				foreach($_POST['quiz_answer'] as $qid => $aid) {
					if(is_array($q[$qid]['correct'])) {
						$correct = count(array_diff($q[$qid]['correct'], (array)$aid)) == 0;
						$correct = $correct && count(array_diff((array)$aid, $q[$qid]['correct'])) == 0;
					}
					else {
						$correct = $aid == $q[$qid]['correct'][0];
					}
					if(isset($q[$qid]['incorrectmessage']) && !$correct) {
						$output .= '<div class="quiz_incorrect"><div>That answer was incorrect.</div>' . $q[$qid]['incorrectmessage'];
						if(isset($q[$qid]['attempts']) && (($quizstate['badanswers'][$qid]['count'] + 1) >= $q[$qid]['attempts'])) {
							$output .= '<div>Maximum attempts exceeded.</div></div>';
							$quizstate['answers'][$qid] = $aid;
						}
						else {
						 $output .= '<div>Try again.</div></div>';
						}
					}
					else {
						if(isset($q[$qid]['correctmessage']) && $correct) {
							$output .= '<div class="quiz_correct"><div>That answer was correct.</div>' . $q[$qid]['correctmessage'] . '</div>'; 
						}
						$quizstate['answers'][$qid] = $aid;
					}
					if(!$correct) {
						$quizstate['badanswers'][$qid]['count'] = isset($quizstate['badanswers'][$qid]) ? $quizstate['badanswers'][$qid]['count'] + 1 : 1;
						if(!isset($quizstate['badanswers'][$qid]['answer'])) $quizstate['badanswers'][$qid]['answer'] = $aid; 
					}
				}
			}
			
			$qid = 0;
			foreach($q as $k=>$question) {
				if(!isset($quizstate['answers']) || !isset($quizstate['answers'][$k])) {
					$qid = $k;
				}
			}
			if($qid == 0) {
				$output .= '<p>Section complete.</p>';
				$quizstate['step'] = 1;
				$output .= '<div class="quiz_controls"><input type="submit" name="action" value="Return to Menu" /></div>';
			}
			else {
				$output .= '<div class="quiz_question">' . $q[$qid]['question'] . '</div>';
				$output .= '<ul class="quiz_answers">';
				$inputtype = count($q[$qid]['correct']) > 1 ? 'checkbox' : 'radio';   
				foreach($q[$qid]['answers'] as $aid => $answer) {
					if(count($q[$qid]['correct']) > 1) {
						$output .= '<li><label class="quiz_answer"><input type="checkbox" name="quiz_answer[' . $qid . '][]" value="' . $aid . '"/> ' . $answer . '</label></li>';
					}
					else {
						$output .= '<li><label class="quiz_answer"><input type="radio" name="quiz_answer[' . $qid . ']" value="' . $aid . '"/> ' . $answer . '</label></li>';
					}
				}
				$output .= '</ul>';
				if(isset($q[$qid]['info'])) {
					$output .= '<div class="quiz_info">' . $q[$qid]['info'] . '</div>';
				}
				$output .= '<div class="quiz_controls"><input type="submit" name="action" value="Return to Menu" /> <input type="submit" name="action" value="Answer and Proceed" /></div>';
			}
			break;
		case 4:
			$output .= '<div class="quiz_results">';
			$output .= '<p>Here are the results of your quiz.</p>';
			$q = $this->get_questions($quiztext);
			foreach($q as $section =>$questions) {
				$output .= '<h3>' . $section . '</h3>';
				$incorrect = array();
				$ccount = 0;
				$icount = 0;
				foreach($questions as $qid=>$question) {
					$correct = !isset($quizstate['badanswers'][$qid]);
					if($correct) {
						$ccount++;
					}
					else {
						$incorrect[$qid] = array($question['question'], $question['correct'], $quizstate['answers'][$qid], $quizstate['badanswers'][$qid]['count']);
						$icount++;
					}
				}
				$tccount += $ccount;
				$ticount += $icount;
				$output .= "<p>Correct answers in this section: {$ccount} out of " . ($icount + $ccount) . "</p>";
				if($icount > 0) {
					foreach($incorrect as $qid => $question) {
						$output .= '<div class="quiz_question">' . $question[0] . '</div>';
						$output .= '<div class="quiz_incorrect"><div>Your first answer</div><ul>';
						if(is_array($quizstate['badanswers'][$qid]['answer'])) {
							foreach($quizstate['badanswers'][$qid]['answer'] as $answer) {
								$output .= '<li>' . $questions[$qid]['answers'][$answer] . '</li>';
							}
						}
						else {
							$output .= '<li>' . $questions[$qid]['answers'][$quizstate['badanswers'][$qid]['answer']] . '</li>';
						}
						$output .= '</ul></div>'; 
						if($question[3] > 1) $output .= '<div class="quiz_timesanswered">Answered incorrectly ' . $question[3] . ' times.</div>'; 
						$output .= '<div class="quiz_correct"><div>The correct answer</div><ul>';
						foreach($question[1] as $answer) {
							$output .= '<li>' . $questions[$qid]['answers'][$answer] . '</li>';
						}
						$output .= '</ul></div>'; 
					}
				}
			}
			
			$output .= '';
		}
		
		
		$output .= '<input type="hidden" name="quizstate" value="' . base64_encode(gzcompress(serialize($quizstate), 9)) . '" />';
		if(isset($quizstate['start'])) $output .= '<div class="quiz_timer">Quiz time: ' . floor((time() - $quizstate['start']) / 60) . ' minutes</div>';
		$output .= '</form>';
		
		
		return $output;
	}
	
	function get_welcome($pg)
	{
		if(preg_match('/^.*?(?===)/s', $pg, $matches))	return $matches[0];
		return "Welcome!";
	}
	
	function get_menu($pg, $quizstate, &$complete)
	{
		$q = $this->get_questions($pg);
		
		$output = '<ul class="quiz_sections">';
		$selected = ' checked="checked"';
		$complete = true;
		foreach($q as $section => $questions) {
			$qcount = 0;
			$acount = 0;
			foreach($questions as $qid=>$question) {
				if(isset($quizstate['answers'][$qid])) $acount++;
				$qcount++;
			}
			if($qcount == $acount) {
				$output .= '<li class="complete"><label><input type="radio" name="quizsection" value="' . $section . '" />' . $section . ' <span class="quizanswercount">(Complete)</span></label></li>';
			}
			else {
				$output .= '<li><label><input type="radio" name="quizsection" value="' . $section . '" ' . $selected . '/>' . $section . ' <span class="quizanswercount">(Answered ' . $acount . '/' . $qcount .')</span></label></li>';
				$selected = '';
				$complete = false;
			}
		}
		$output .= '</ul>';
		return $output;
	}
	
	function get_questions($pg)
	{
		if(isset($this->qarray)) return $this->qarray;
		
		preg_match_all('/==(.*?)==.*?(?=^==|\\z)/sm', $pg, $matches, PREG_SET_ORDER);
		foreach($matches as $match) {
			preg_match_all('/Q:.*?(?=^==|Q:|\\z)/sm', $match[0], $questiontexts, PREG_SET_ORDER);
			foreach($questiontexts as $questiontext) {
				preg_match('/^Q:(.*?)(?=^[A-Z]\\*?:)/sm', $questiontext[0], $question);
				$qid++;// = md5($question[1]);
				$sections[$match[1]][$qid]['question'] = $question[1];
				preg_match_all('/^A(\*?):(.*?)(?=^[A-Z]\\*?:|\\z)/sm', $questiontext[0], $answers, PREG_SET_ORDER);
				$acount = 0;
				foreach($answers as $answer) {
					if($answer[1] == '*') $sections[$match[1]][$qid]['correct'][] = $acount;
					$acount++;
					$sections[$match[1]][$qid]['answers'][] = trim($answer[2]);
				}
				if(preg_match('/^I:(.*?)(?=^[A-Z]\\*?:|\\z)/sm', $questiontext[0], $infos)) {
					$sections[$match[1]][$qid]['info'] = trim($infos[1]);
				}
				if(preg_match('/^Y:(.*?)(?=^[A-Z]\\*?:|\\z)/sm', $questiontext[0], $infos)) {
					$sections[$match[1]][$qid]['correctmessage'] = trim($infos[1]);
				}
				if(preg_match('/^N:(.*?)(?=^[A-Z]\\*?:|\\z)/sm', $questiontext[0], $infos)) {
					$sections[$match[1]][$qid]['incorrectmessage'] = trim($infos[1]);
				}
				if(preg_match('/^M:(.*?)(?=^[A-Z]\\*?:|\\z)/sm', $questiontext[0], $infos)) {
					$sections[$match[1]][$qid]['attempts'] = intval($infos[1]);
				}
			}
		}
		$this->qarray = $sections;
		return $sections;
	}
}
